package cn.com.jinhao.provider.business.service.impl;

import cn.com.jinhao.hotline.commons.base.constant.SystemConstant;
import cn.com.jinhao.hotline.commons.exception.BusinessErrorException;
import cn.com.jinhao.hotline.commons.util.ExeclUtil;
import cn.com.jinhao.hotline.commons.vo.business.RecordInfoRequestVO;
import cn.com.jinhao.hotline.commons.vo.business.record.RecordEventCondition;
import cn.com.jinhao.hotline.commons.vo.business.record.TapeRequest;
import cn.com.jinhao.provider.business.entity.RecordInfo;
import cn.com.jinhao.provider.business.entity.Wkfl;
import cn.com.jinhao.provider.business.mapper.RecordInfoMapper;
import cn.com.jinhao.provider.business.service.*;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.*;

/**
 * hotline-spring-cloud
 * <p>Description: </p>
 *
 * @author ShaneMew
 * @version 1.0
 * @date 2020/1/13
 * @since 2020-01-13
 */

@Service
public class RecordInfoServiceImpl extends CommonService implements RecordInfoService {
    @Resource
    private RecordInfoMapper recordInfoMapper;
    @Resource
    private TapeService tapeService;
    @Resource
    private FeignService feignService;
    @Resource
    private WorkflowService workflowService;
    @Resource
    private WorkTerminalCacheService workTerminalCacheService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public String add(RecordInfoRequestVO recordInfoRequestVO) throws Exception {
        RecordInfo recordInfo = new RecordInfo();
        BeanUtil.copyProperties(recordInfoRequestVO, recordInfo);

        // 检查记录人员是否在库
        String recordManName = Optional.ofNullable(feignService.getUsernameByCode(recordInfo.getOperCode())).orElseThrow(() -> new BusinessErrorException("记录人员不存在"));

        // 检查记录人员部门是否存在
        String recordManDeptName = Optional.ofNullable(feignService.queryDeptNameByCode(recordInfo.getOperDeptCode())).orElseThrow(() -> new BusinessErrorException("记录人员部门编码错误"));

        if (!recordManName.equals(recordInfo.getOperName())) {
            throw new BusinessErrorException("记录人员名称错误");
        } else if (!recordManDeptName.equals(recordInfo.getOperDeptName())) {
            throw new BusinessErrorException("记录人员部门名称错误");
        }
        String code = super.getCode(SystemConstant.CodeType.SIMPLE) + recordInfo.getOperDeptCode();
        recordInfo.setCode(code);
        recordInfo.setVersion(1);

        // 获得过期日期
        recordInfo.setExpireDatetime(getExpiredDate(recordInfo.getAppealTime()));

        // 记录事件状态更新为待派单的状态
        recordInfo.setEventStatus(SystemConstant.FlowStatus.DISPATCH.getStatus());
        recordInfo.setEventStatusCode(SystemConstant.FlowStatus.DISPATCH.getStatusCode());

        recordInfoMapper.insertSelective(recordInfo);

        // 删除接线工作台的缓存信息
        workTerminalCacheService.delete(recordInfo.getCallId());

        // 录音文件关联
        List<TapeRequest> tapeRequestList = recordInfoRequestVO.getTapeRequestList();
        if (!tapeRequestList.isEmpty()) {
            tapeRequestList.forEach(item -> item.setEventCode(code));
            tapeService.addBatch(tapeRequestList);
        }



        // 流程状态暂时停用
        Wkfl wkfl = new Wkfl();
        wkfl.setBtEvifCode(code);
        wkfl.setEvcuCode(SystemConstant.FlowStatus.DISPATCH.getStatusCode());
        wkfl.setEvcuPaid(SystemConstant.FlowStatus.UNDISPATCH.getStatusCode());
        wkfl.setWkfl(recordInfo.getOperName() + " 记录了事件");
        wkfl.setStDeptCodea(recordInfo.getOperDeptCode());
        wkfl.setStDeptDepta(recordInfo.getOperDeptName());
        wkfl.setStOperCodea(recordInfo.getOperCode());
        wkfl.setStOperOpera(recordInfo.getOperName());
        boolean add_wkfl_bool = workflowService.insert(wkfl);
        if (!add_wkfl_bool) {
            throw new IllegalStateException(this.getClass().getName() + "流程信息新增出错");
        }

        return code;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(RecordInfoRequestVO recordInfoRequestVO) throws Exception {
        RecordInfo recordInfo = new RecordInfo();
        BeanUtil.copyProperties(recordInfoRequestVO, recordInfo);
        Example example = new Example(RecordInfo.class);
        example.createCriteria().andEqualTo("code", recordInfoRequestVO.getCode()).andEqualTo("version", recordInfoRequestVO.getVersion());
        recordInfo.setVersion(recordInfoRequestVO.getVersion() + 1);
        int result = recordInfoMapper.updateByExample(recordInfo, example);
        if (result == 0) {
            throw new BusinessErrorException("当前事件已经发生变更!");
        }

        // 更新录音文件的相关
        tapeService.delete(recordInfo.getCode());
        tapeService.addBatch(recordInfoRequestVO.getTapeRequestList());
    }

    @Override
    public RecordInfo selectByCode(String code) {
        Example example = new Example(RecordInfo.class);
        example.createCriteria().andEqualTo("code", code);
        return recordInfoMapper.selectOneByExample(example);
    }

    @Override
    public Map<String, Object> selectByCondition(RecordEventCondition conditions) {
        HashMap<String, Object> map = new HashMap<>(10);
        Example example =  getExample(conditions);
        if (conditions.getIsExport()) {
            List<RecordInfo> recordInfos = recordInfoMapper.selectByExample(example);
            List<String> headers = conditions.getHeaders();
            JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(recordInfos));
            String fileInfo = new ExeclUtil().exportExecl(headers,jsonArray,"F:\\");
            map.put("fileInfo", fileInfo);
        } else {
            if (conditions.getPageNo() != 0 && conditions.getPageSize() != 0) {
                PageHelper.startPage(conditions.getPageNo(), conditions.getPageSize());
                PageInfo<RecordInfo> pageInfo = new PageInfo<>(recordInfoMapper.selectByExample(example));
                map.put("list", pageInfo);
                map.put("total", pageInfo.getTotal());
                map.put("pageSize", pageInfo.getPageSize());
                map.put("pageNo", pageInfo.getPageNum());
            } else {
                List<RecordInfo> recordInfos = recordInfoMapper.selectByExample(example);
                map.put("list", recordInfos);
                map.put("total", recordInfos.size());
            }
        }
        return map;
    }

    Example getExample(RecordEventCondition conditions) {
        Example example = new Example(RecordInfo.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("stat", 1);
        if (ObjectUtil.isNotNull(conditions.getEventType())) {
            for (SystemConstant.EventType e : SystemConstant.EventType.values()) {
                if (e.getIndex() == conditions.getEventType()) {
                    criteria.andEqualTo(e.getName(), 1);
                }
            }
        }

        if (StringUtils.isNotBlank(conditions.getDispatchWayCode())) {
            criteria.andEqualTo("dispatchWayCode", conditions.getDispatchWayCode());
        }
        example.setOrderByClause("'createTime' desc, 'modifyTime' desc");
        return example;
    }
}
